/*
 * CMediaStorageChannel.h
 *
 *  Created on: 2018年7月29日
 *      Author: zhengboyuan
 */

#ifndef CMEDIASTORAGECHANNEL_H_
#define CMEDIASTORAGECHANNEL_H_

#include "MediaStorage.h"
#include "MediaWriter.h"
#include "SharedPtr.h"
#include "TCriticalSection.h"
#include "DataStore.h"
#include "MediaStorage.h"
#include "MediaFormat.h"
#include "H264PropDetector.h"
#include "NaluJoiner.h"
#include "StorageChannelThread.h"
#include "TMap.h"


namespace av
{

typedef std::shared_ptr< MediaWriter >  MediaWriterPtr;

class CMediaStorageChannel: public MediaStorageChannel , public MediaStorageSink, public MediaWriterListener
{
public:
    
    static std::string getName(int id);

    /// 根据录像文件路径获取事件文件路径
    static std::string getEventFilePath(const char* recPath, size_t length);

    static std::string makeRecordName(int id);

    static std::string getFileExt(RecordFileFormat fmt);

    static bool forceAac;

    static bool enableSubDir;

    static std::string  nameTemplate;

public:
    CMediaStorageChannel();
    virtual ~CMediaStorageChannel();

    virtual bool open(const char* device);
    virtual void close();
    virtual bool isOpen();

    virtual const std::string& getName();


    virtual const char* getDevice();

    virtual bool startRecord(const MFormat& fmt);

    virtual void stopRecord();

    virtual int writeVideo(uint8_t* data, int size, int64_t pts);

    virtual int writeAudio(uint8_t* data, int size, int64_t pts);

    virtual void setFileFormat(RecordFileFormat fileFormat);

    virtual void setFileDuration(int seconds);

    virtual void setName(const char* name);

    virtual bool setRecordNameTemplate(const char* tmpl);

    virtual bool setDirTemplate(const char* tmpl);

    virtual void setRecordNameVar(char charHolder, const char* value);

    virtual int writeVideoEx(uint8_t* data, int size, int64_t pts, int flags);

    virtual void setRecordType(int recordType);

    virtual void setRecorder(const char* recorder);



    bool setRecordDir(const std::string& path);

    std::string getPath();

    bool writeEvent(AlarmEvent& event);

    std::string makeRecordPath();

    void setSink(MediaStorageSink* sink);

    void setDataStore(DataStorePtr& dataStore);




    bool openRecord(const std::string& recordPath);
    void closeRecord();
    bool isRecordOpen();
    void switchRecord();

    void fireStorageEvent(const StorageEvent& event);

    virtual void onStorageEvent(const StorageEvent& event);

    virtual void onWriteStatus(MediaWriter* writer, int status);


protected:
    bool isVideoPropReady();

    int getRecordingDuration();

    bool isStarted();

    std::string makeDirName();
    std::string makeFileName();

    std::string makeFileName(const std::string& templ);

protected:
    std::string m_device;
    std::string m_name; /// subdir

    RecordFileFormat    m_fileFormat;
    int m_fileDuration;
    std::string m_rootPath;

    std::string m_recordPath;
    int m_recordEvents;

    MediaFormat m_format;

    comn::CriticalSection   m_cs;

    MediaWriterPtr  m_writer;
    MRecord m_record;
    int64_t m_byteCount;
    time_t  m_startTime;
    int     m_recordType;
    std::string m_recorder;

    MediaStorageSink*   m_sink;
    DataStorePtr    m_dataStore;

    H264PropDetector    m_propDetector;
    std::shared_ptr< NaluJoiner >   m_naluJoiner;

    StorageChannelThread    m_chlThread;

    std::string m_dirTemplate;
    std::string m_nameTemplate;

    comn::Map< std::string, std::string >   m_varMap;

};


typedef std::shared_ptr< MediaStorageChannel >   MediaStorageChannelPtr;
typedef std::shared_ptr< CMediaStorageChannel >  CMediaStorageChannelPtr;


} /* namespace av */

#endif /* CMEDIASTORAGECHANNEL_H_ */
